package com.photographysharing.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.photographysharing.annotation.RoleAnnotation;
import com.photographysharing.common.ThreadLocalOperation;
import com.photographysharing.dto.PwdChangeDTO;
import com.photographysharing.entity.Users;
import com.photographysharing.exception.ServiceException;
import com.photographysharing.request.AccountRequest;
import com.photographysharing.response.MessageResponse;
import com.photographysharing.response.SignResponse;
import com.photographysharing.service.MailService;
import com.photographysharing.service.UsersService;
import com.photographysharing.util.JWTUtil;
import com.photographysharing.util.RedisHelp;
import org.springframework.web.bind.annotation.*;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

@RestController
@RequestMapping("/identity")
public class IdentityController {
    private UsersService usersService;
    private RedisHelp redisHelp;
    private MailService emaiService;
    public IdentityController(UsersService usersService, RedisHelp redisHelp, MailService emaiService) {
        this.usersService = usersService;
        this.redisHelp = redisHelp;
        this.emaiService = emaiService;
    }




    /**
     * 检查邮箱
     * @param email
     * @return
     */
    @GetMapping("/checkEmail")
    public MessageResponse checkEmail(String email){
        if(usersService.checkEmail(email)){
            return new MessageResponse("当前邮箱已注册!",false);
        }
        return  new MessageResponse("当前邮箱未注册!");
    }

    @GetMapping("/getRole")
    public String  getRole(){
        return ThreadLocalOperation.getThreadLocaclRole();
    }

    @PostMapping("/login")
    public SignResponse login(@RequestBody AccountRequest account){
        String email = account.getEmail();
        Users user = usersService.getOne(new QueryWrapper<Users>().eq("email",email));
        return checkPassword(user,account.getPassword());
    }

    @PostMapping("/loginByUserName")
    public SignResponse loginByUserName(@RequestBody AccountRequest account){
        QueryWrapper<Users> qw = new QueryWrapper<Users>();
        qw.eq("user_name",account.getUserName());
        Users user = usersService.getOne(qw);
        return checkPassword(user,account.getPassword());
    }

    @PostMapping("loginByAdmin")
    public SignResponse loginByAdmin(@RequestBody AccountRequest account){
        QueryWrapper<Users> qw = new QueryWrapper<>();
        qw.eq("user_name",account.getUserName());
        qw.like("role_name","ad");
        Users user = usersService.getOne(qw);
        return checkPassword(user,account.getPassword());

    }

    private SignResponse checkPassword(Users user,String password){
        if(user!= null){
            password = getSHA256Hash(password);
            if(user.getPassword().equals(password)){
                String token = JWTUtil.generateToken(user);
                return new SignResponse("登录成功!",token);
            }
        }
        return  new SignResponse("请检查账号或密码!",false);
    }


    @RequestMapping("/register")
    public MessageResponse register(@RequestBody AccountRequest account){
        try{
            if(!usersService.checkEmail(account.getEmail())){
                String code = redisHelp.getString(account.getEmail());
                if(code.equals(account.getCode())){
                    redisHelp.removeKey(account.getEmail());
                    String password = getSHA256Hash(account.getPassword());
                    Users user = new Users("用户"+account.getEmail(),account.getEmail(),password);
                    if(usersService.save(user)){
                        return  new MessageResponse("注册成功!");
                    }
                    return  new MessageResponse("注册失败!",false);
                }else{
                    return  new MessageResponse("验证码不存在!",false);
                }
            }else{
                return  new MessageResponse("当前邮箱已存在!",false);
            }
        }catch (Exception e){
            throw  new ServiceException(500,"系统错误!");
        }

    }
    @RequestMapping("/registerByEmailAndCode")
    public SignResponse registerByEmailAndCode(@RequestBody AccountRequest account){
        try{
            String code = redisHelp.getString(account.getEmail());
            if(code.equals(account.getCode())){
                redisHelp.removeKey(account.getEmail());
                String password = getSHA256Hash(generatePassword());
                Users user = new Users("用户"+account.getEmail(),account.getEmail(),password);
                if(usersService.save(user)){
                    user = usersService.getOne(new QueryWrapper<Users>().eq("email",account.getEmail()));
                    String token = JWTUtil.generateToken(user);
                    return new SignResponse("登录成功!",token);
                }
                return  new SignResponse("注册失败!",false);
            }else{
                return  new SignResponse("验证码不存在!",false);
            }
        }catch (Exception e){
            throw  new ServiceException(500,"系统错误!");
        }
    }

    @PostMapping("/loginByEmailAndCode")
    public SignResponse loginByEmailAndCode(@RequestBody AccountRequest account){
        try{
            String code = redisHelp.getString(account.getEmail());
            if(code.equals(account.getCode())){
                redisHelp.removeKey(account.getEmail());
                Users user = usersService.getOne(new QueryWrapper<Users>().eq("email",account.getEmail()));
                if(user != null){
                    String token = JWTUtil.generateToken(user);
                    return new SignResponse("登录成功!",token);
                }else{
                    return new SignResponse("邮箱不存在!",false);
                }
            }else {
                return new SignResponse("验证码不存在!",false);
            }

        }catch (Exception e){
            throw new ServiceException("系统错误!");
        }
    }

    @RequestMapping("/sendEmail")
    @GetMapping
    public MessageResponse sendEmail(String email){
        try{
            String code = creatCode(6);
            redisHelp.setString(email,code,15);
            return emaiService.sendCodeMailMessage(email,code);
        }catch (Exception e){
            throw new ServiceException(500,"系统错误!");
        }
    }
    @GetMapping("/sendEmailByMyself")
    public MessageResponse sendEmailByMyself(){
        String email = ThreadLocalOperation.getThreadLocaclEmail();
        return sendEmail(email);
    }

    @GetMapping("/checkCodeByEmail")
    public MessageResponse checkCodeByEmail(String code){
        String email = ThreadLocalOperation.getThreadLocaclEmail();
        String json = redisHelp.getString(email);
        if(code.equals(json)){
            return new MessageResponse("验证成功!");
        }
        return new MessageResponse("验证失败!",false);
    }

    @PostMapping("/passwordChangeByEmailAndCode")
    public MessageResponse passwordChangeByEmailAndCode(@RequestBody PwdChangeDTO pwd){
       try{
           String email = ThreadLocalOperation.getThreadLocaclEmail();
           String userId = ThreadLocalOperation.getThreadLocalUserId();
           if(checkCodeByEmail(pwd.getCode()).isSuccess()){
               redisHelp.removeKey(email);
               String password = getSHA256Hash(pwd.getPassword());
               Users user = usersService.getById(userId);
               if(user == null){
                   return new MessageResponse(401,"请重新登录!",false);
               }
               user.setPassword(password);
               if(usersService.updateById(user)){
                   return new MessageResponse("密码修改成功!");
               }
               return new MessageResponse("密码修改失败!",false);
           }
           return new MessageResponse("验证码不匹配!",false);
       }catch (Exception e){
           return  null;
       }
    }





    private  String creatCode(int n) {

        String code = "";
        Random r = new Random();
        for (int i = 0; i < n; i++) {
            code +=  r.nextInt(10);
        }
        return code;
    }

    private String getSHA256Hash(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hashBytes = digest.digest(str.getBytes(StandardCharsets.UTF_8));
            StringBuilder hexString = new StringBuilder();
            for (byte b : hashBytes) {
                String hex = Integer.toHexString(0xff & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return null;
    }
    public static String generatePassword() {
        SecureRandom random = new SecureRandom();
        StringBuilder password = new StringBuilder(16);
        String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_@!#$%^&*()";
        for (int i = 0; i < 16; i++) {
            int randomIndex = random.nextInt(characters.length());
            char randomChar = characters.charAt(randomIndex);
            password.append(randomChar);
        }

        return password.toString();
    }
}
